/*
 * MidiType.java
 *
 * Created on July 31, 2007, 7:46 PM
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package tal.drivechain.variable.types;

import javax.sound.midi.MidiMessage;
import javax.sound.midi.ShortMessage;
import tal.drivechain.chain.ChainNode;
import tal.drivechain.matchers.ValueMatcher;
import tal.drivechain.midi.MidiMatcher;
import tal.drivechain.midi.MidiParser;
import tal.drivechain.midi.MidiUtility;
import tal.drivechain.variable.expressions.CustomExpression;
import tal.drivechain.variable.expressions.MidiExpression;

/**
 * A DataType class that handles MIDI messages. Uses {@link MidiParser} to parse its value.
 * Name: "midi"
 * Value object: {@link MidiMessage}
 * Type code: 6
 * Syntax: midi:<{@link MidiParser} syntax> (basically midi:cmd/data1/data2/channel).
 * Can't cast at the moment from any data type. 
 *
 * @author Tal Eisenberg
 */
public final class MidiType extends DataType {
    public MidiType() {
        super("midi", MidiMessage.class, 6);
    }

    public final Object parseValue(String value) throws IllegalArgumentException {
        return new MidiParser(value).getMidiMessage(null);
    }
    
    @Override
    public final String toString(Object value, ChainNode context) {
        if (value instanceof ShortMessage) {
            ShortMessage smsg = (ShortMessage)value;
            String command = MidiUtility.commandCodeToString(smsg.getCommand());
            String data1;
            if (smsg.getCommand()==ShortMessage.NOTE_OFF || smsg.getCommand()==ShortMessage.NOTE_ON)
                data1 = MidiUtility.noteNumberToString(smsg.getData1());
            else data1 = "" + smsg.getData1();
            return command + "/" + data1 + "/" + smsg.getData2() + "/" + smsg.getChannel();
        } else {
            return MidiUtility.midiToString((MidiMessage)value);
        }

    }

    @Override
    public CustomExpression createExpression(String value) throws IllegalArgumentException {
        return new MidiExpression(value, this);
    }

    @Override
    public ValueMatcher createValueMatcher() throws IllegalArgumentException {
        return new MidiMatcher();
    }

}
